Constants (C++)
The concept of a user-defined constant, a **const**, express the notion that a value doesn't change directly. This is useful in several contexts. For example, many objects don't actually have their values changed after initialization, symbolic constants lead to more maintainable code than do literals embedded directly in code, pointers are often read through but never written through, and most function parameters are read but not written to. The keyword const can be added to the declaration of an object to make the object declared a constant. Because it cannot be assigned to, a constant must be initialized. For example: const int model = 90; // model is a const const int v[] = {1, 2, 3, 4}; // vi is a const const int x; // error: no initializer A compiler can take advantage of an object being a constant in several ways. For example, the initializer for a constant is often (but not always) a constant expression; if it is, it can be evaluated at compile time. Further, if the compiler knows every use of the const, it need not allocate space to hold it. For example: const int c1 = 1; const int c2 = 2; const int c3 = my_f(3); // don't know the value of c1 at compile time extern const int c4; // don't know the value of c2 at compile time const int* p = &c2; // need to allocate space for c; Given this, the compiler knows the values of c1 and c2 so that they can be used in constant expressions. Because the values of c3 and c4 are not known at compile time, storage must be allocated for c3 and c4. Because the address of c2 is taken, storage must be allocated for c2. The simple and common case is the one in which the value of the constant is known at compile time and no storage needs to be allocated; c1 is an example of that. The keyword extern indicates that c4 is defined elsewhere. Common uses for consts are as array bounds and case labels. For example: const int a = 42; const int b = 99; const int max = 128; int vmax; void f(int i) { switch (i) { case a: // ... case b: // ... } } Enumerators are often an alternative to consts in such cases. Pointers and Constants When using a pointer, two objects are involved: the pointer itself and the object pointed to. Declare a pointer as const makes the object, but not the pointer, a constant. To declare a pointer itself, rather than the object pointed to, we use the declarator operator * const instead of plain *. For example: void f1(char* p) { char s[] = "Gorm"; const char* pc = s; // pointer to constant pc3 = 'g'; // error: pc points to constant pc = p; // ok char *const cp = s; // constant pointer cp3 = 'a'; // ok cp = p; // error: cp is constant const char *const cpc = s; // const pointer to const cpc3 = 'a'; // error: cpc points to constant cpc = p; // error: cpc is constant } The declarator operator that makes a pointer constant is *const. A const appearing before the * is taken to be part of the base type. For example: char *const cp; // const pointer to char char const *pc; // pointer to const char const char* pc2; // pointer to const char An object that is a constant when accessed through one pointer may be variable when accessed in other ways. This is particularly useful for function arguments. By declaring a pointer argument const, the function is prohibited from modifying the object pointed to. For example: char* strcpy(char* p, const char*q) // cannot modify *q Constant Member Functions A const after the argument list in a function declaration indicates that the function do not modify the state of the class/object. Naturally, the compiler will catch accidental attempts to violate this promise. For example: inline int Date::year() const { return y++; // error: attempt to change member value in const function } When a const member function is defined outside its class, the const suffix is required: inline int Date::year() // error: const missing in member function type { return y; } A const member function can be invoked for both const and non-const objects, whereas a non-const member function can be invoked only for non-const objects. References Category:C++